#!/bin/bash

# 分布式存储系统 - 完整功能测试脚本

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

ROOT_DIR=$(cd $(dirname $0); pwd)

echo -e "${BLUE}=== 分布式存储系统 - 完整功能测试 ===${NC}"
echo ""

# 配置参数
CHUNKMASTER_PORT=50050
CHUNKSERVER_BASE_PORT=50051
CHUNKSERVER_COUNT=6

# 检查依赖
echo -e "${YELLOW}1. 检查系统依赖...${NC}"

# 检查netcat
if ! command -v nc &> /dev/null; then
    echo -e "${RED}错误: 需要安装netcat (nc)${NC}"
    echo "macOS: brew install netcat"
    exit 1
fi

# 检查可执行文件
CHUNKMASTER_BIN="$ROOT_DIR/persistent_layer/chunkmaster/build/chunkmaster"
CHUNKSERVER_BIN="$ROOT_DIR/persistent_layer/chunkserver/build/chunkserver_server"
CLIENT_BIN="$ROOT_DIR/persistent_layer/chunkserver/build/chunkserver_client"

if [ ! -f "$CHUNKMASTER_BIN" ]; then
    echo -e "${RED}错误: 找不到chunkmaster可执行文件${NC}"
    exit 1
fi

if [ ! -f "$CHUNKSERVER_BIN" ]; then
    echo -e "${RED}错误: 找不到chunkserver可执行文件${NC}"
    exit 1
fi

if [ ! -f "$CLIENT_BIN" ]; then
    echo -e "${RED}错误: 找不到chunkserver_client可执行文件${NC}"
    exit 1
fi

echo -e "${GREEN}✓ 所有依赖检查通过${NC}"

# 清理之前的进程
echo -e "${YELLOW}2. 清理之前的进程...${NC}"
pkill -f "chunkmaster" 2>/dev/null
pkill -f "chunkserver_server" 2>/dev/null
sleep 2

# 创建日志目录
mkdir -p logs

# 启动chunkmaster
echo -e "${YELLOW}3. 启动chunkmaster服务...${NC}"
cd "$ROOT_DIR/persistent_layer/chunkmaster/build"

# 复制配置文件到build目录
cp ../config.json . 2>/dev/null || echo "配置文件已存在"

# 使用yes命令防止chunkmaster因无输入而退出
yes "" | nohup ./chunkmaster > "$ROOT_DIR/logs/chunkmaster.log" 2>&1 &
CHUNKMASTER_PID=$!
cd "$ROOT_DIR"

# 等待chunkmaster启动
sleep 3

# 检查chunkmaster是否启动成功（使用多种方法检测）
echo -e "${BLUE}检查chunkmaster启动状态...${NC}"

# 方法1: 检查进程是否还在运行
if ! kill -0 $CHUNKMASTER_PID 2>/dev/null; then
    echo -e "${RED}错误: chunkmaster进程已退出${NC}"
    echo -e "${YELLOW}查看日志:${NC}"
    cat logs/chunkmaster.log
    exit 1
fi

# 方法2: 检查端口是否监听
PORT_CHECK_SUCCESS=false
for i in {1..15}; do
    if lsof -iTCP:$CHUNKMASTER_PORT -sTCP:LISTEN >/dev/null 2>&1; then
        echo -e "${GREEN}✓ chunkmaster端口检测成功 (尝试 $i/15)${NC}"
        PORT_CHECK_SUCCESS=true
        break
    fi
    sleep 1
done

# 方法3: 检查日志中是否有成功启动的信息
if grep -q "gRPC服务已启动" logs/chunkmaster.log; then
    echo -e "${GREEN}✓ chunkmaster日志显示启动成功${NC}"
    LOG_CHECK_SUCCESS=true
else
    echo -e "${YELLOW}警告: 日志中未找到启动成功信息${NC}"
    LOG_CHECK_SUCCESS=false
fi

# 综合判断
if [ "$PORT_CHECK_SUCCESS" = true ] || [ "$LOG_CHECK_SUCCESS" = true ]; then
    echo -e "${GREEN}✓ chunkmaster启动成功 (PID: $CHUNKMASTER_PID)${NC}"
else
    echo -e "${YELLOW}警告: 端口检测失败，但进程仍在运行${NC}"
    echo -e "${YELLOW}继续执行，chunkmaster可能正在启动中...${NC}"
fi

# 启动多个chunkserver
echo -e "${YELLOW}4. 启动 $CHUNKSERVER_COUNT 个chunkserver进程...${NC}"
CHUNKSERVER_PIDS=()

for ((i=0; i<CHUNKSERVER_COUNT; i++)); do
    PORT=$((CHUNKSERVER_BASE_PORT + i))
    echo -e "${BLUE}启动 chunkserver_$i 在端口 $PORT...${NC}"
    
    # 使用yes命令防止chunkserver因无输入而退出
    yes "" | nohup $CHUNKSERVER_BIN $PORT > "$ROOT_DIR/logs/chunkserver_$i.log" 2>&1 &
    PID=$!
    CHUNKSERVER_PIDS+=($PID)
    
    sleep 1
    
    if kill -0 $PID 2>/dev/null; then
        echo -e "${GREEN}✓ chunkserver_$i 启动成功 (PID: $PID, 端口: $PORT)${NC}"
    else
        echo -e "${RED}✗ chunkserver_$i 启动失败${NC}"
        exit 1
    fi
done

echo -e "${GREEN}✓ 所有chunkserver启动成功${NC}"

# 等待服务完全启动
sleep 2

# 启动client进行测试
echo -e "${YELLOW}5. 启动client进行功能测试...${NC}"

# 创建测试脚本
cat > test_commands.txt << 'EOF'
allocate
show meta
write test_data_1
read 0 12
use 1
show meta
write_chunk 1 chunk1_data
read_chunk 1 0 12
allocate
show meta
write test_data_2
read 0 12
exit
EOF

echo -e "${BLUE}执行测试命令...${NC}"
cd "$ROOT_DIR/persistent_layer/chunkserver/build"
./chunkserver_client < "$ROOT_DIR/test_commands.txt" > "$ROOT_DIR/logs/client_test.log" 2>&1
cd "$ROOT_DIR"

# 检查测试结果
echo -e "${YELLOW}6. 检查测试结果...${NC}"
if grep -q "成功" logs/client_test.log; then
    echo -e "${GREEN}✓ 客户端测试成功${NC}"
else
    echo -e "${RED}✗ 客户端测试失败${NC}"
    echo "查看日志: tail -f logs/client_test.log"
fi

# 显示系统状态
echo ""
echo -e "${BLUE}=== 系统状态 ===${NC}"
echo "ChunkMaster: PID=$CHUNKMASTER_PID, 端口=$CHUNKMASTER_PORT"
for ((i=0; i<CHUNKSERVER_COUNT; i++)); do
    PID=${CHUNKSERVER_PIDS[$i]}
    PORT=$((CHUNKSERVER_BASE_PORT + i))
    echo "ChunkServer_$i: PID=$PID, 端口=$PORT"
done

echo ""
echo -e "${YELLOW}=== 日志文件 ===${NC}"
echo "ChunkMaster: logs/chunkmaster.log"
for ((i=0; i<CHUNKSERVER_COUNT; i++)); do
    echo "ChunkServer_$i: logs/chunkserver_$i.log"
done
echo "Client测试: logs/client_test.log"

echo ""
echo -e "${YELLOW}=== 测试完成 ===${NC}"
echo "按任意键停止所有服务..."
read -n 1

# 清理函数
cleanup() {
    echo ""
    echo -e "${YELLOW}正在停止所有服务...${NC}"
    
    # 停止chunkmaster
    if kill -0 $CHUNKMASTER_PID 2>/dev/null; then
        echo -e "${BLUE}停止chunkmaster...${NC}"
        kill $CHUNKMASTER_PID
    fi
    
    # 停止所有chunkserver进程（使用pkill确保能停止所有相关进程）
    echo -e "${BLUE}停止所有chunkserver_server进程...${NC}"
    pkill -f "chunkserver_server" 2>/dev/null
    
    # 等待进程结束
    sleep 3
    
    # 强制杀死残留进程
    pkill -f "chunkmaster" 2>/dev/null
    pkill -f "chunkserver_server" 2>/dev/null
    
    # 清理临时文件
    rm -f test_commands.txt
    
    echo -e "${GREEN}所有服务已停止${NC}"
    exit 0
}

# 设置信号处理
trap cleanup SIGINT SIGTERM

# 等待用户中断，添加退出机制
echo -e "${BLUE}按 Ctrl+C 停止所有服务并退出脚本${NC}"
while true; do
    sleep 1
done 